package com.mytx.live;

import com.mytx.common.constant.Constant;
import com.mytx.common.exception.DecodeException;
import com.mytx.common.exception.EncryptException;
import com.mytx.common.exception.RequestExpireException;
import com.mytx.common.exception.TokenException;
import com.mytx.common.pojo.CommonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;

@CrossOrigin
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s";
    private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //运行时异常
    @ExceptionHandler(RuntimeException.class)
    public CommonResult runtimeExceptionHandler(RuntimeException ex) {
        return exceptionFormat(1, ex);
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    public CommonResult nullPointerExceptionHandler(NullPointerException ex) {
        return exceptionFormat(2, ex);
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    public CommonResult classCastExceptionHandler(ClassCastException ex) {
        return exceptionFormat(3, ex);
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    public CommonResult iOExceptionHandler(IOException ex) {
        return exceptionFormat(4, ex);
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    public CommonResult noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        return exceptionFormat(5, ex);
    }

    // 数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public CommonResult indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        return exceptionFormat(6, ex);
    }

    // 400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public CommonResult requestNotReadable(HttpMessageNotReadableException ex) {
        return exceptionFormat(7, ex);
    }

    // 400错误
    @ExceptionHandler({TypeMismatchException.class})
    public CommonResult requestTypeMismatch(TypeMismatchException ex) {
        return exceptionFormat(8, ex);
    }

    // 400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public CommonResult requestMissingServletRequest(MissingServletRequestParameterException ex) {
        return exceptionFormat(9, ex);
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public CommonResult request405(HttpRequestMethodNotSupportedException ex) {
        return exceptionFormat(10, ex);
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public CommonResult request406(HttpMediaTypeNotAcceptableException ex) {
        return exceptionFormat(11, ex);
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public CommonResult server500(RuntimeException ex) {
        return exceptionFormat(12, ex);
    }

    //栈溢出
    @ExceptionHandler({StackOverflowError.class})
    public CommonResult requestStackOverflow(StackOverflowError ex) {
        return exceptionFormat(13, ex);
    }

    //其他错误
    @ExceptionHandler({Exception.class})
    public CommonResult exception(Exception ex) {
        return exceptionFormat(14, ex);
    }

    //自定义异常捕获
    @ExceptionHandler({TokenException.class})
    public CommonResult tokenException(TokenException ex) {
        return exceptionFormat(15, ex);
    }

    //解密异常
    @ExceptionHandler({DecodeException.class})
    public CommonResult decodeException(DecodeException ex) {
        return exceptionFormat(16, ex);
    }

    //加密异常
    @ExceptionHandler({EncryptException.class})
    public CommonResult encryptException(EncryptException ex) {
        return exceptionFormat(17, ex);
    }

    //请求过期异常
    @ExceptionHandler({RequestExpireException.class})
    public CommonResult requestExpireException(RequestExpireException ex) {
        return exceptionFormat(18, ex);
    }

    private <T extends Throwable> CommonResult exceptionFormat(Integer code, T ex) {
        ex.printStackTrace();
        log.error(String.format(logExceptionFormat, code, ex.getMessage()));
        return CommonResult.build(Constant.UNKNOWN_ERROR, "system_busy");
    }


}
